#include "secretkeyactivationwidget.h"
#include "ui_secretkeyactivationwidget.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonParseError>
#include <QJsonObject>
#include <QCryptographicHash>
#include <QGSettings>
#include <QRegExpValidator>

SecretKeyActivationWidget::SecretKeyActivationWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SecretKeyActivationWidget)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
    this->setProperty("useStyleWindowManager",false);
    ui->aclineEdit->setValidator(new QRegExpValidator(QRegExp("[A-Z0-9]+$")));
    ui->activationremindlabel->setVisible(false);
    m_timer=new QTimer;
    connect(m_timer,&QTimer::timeout,this,[=]{
        static int cnt=0;
        Interface interface;
        QPixmap pixmap=interface.getThemeLoadingIcon(cnt);
        ui->activationiconlabel->setPixmap(pixmap);
        cnt++;
        if(cnt==7)
            cnt=0;
    });

    connect(ui->aclineEdit, &QLineEdit::textEdited, [=](QString txt){
        int number = ui->aclineEdit->text().length();
        qDebug()<<"the aclineedit length is"<<number;
        if(number == 20)
        {
            ui->activebtn->setEnabled(true);
        }
        else
        {
            ui->activebtn->setEnabled(false);
        }
    });
}

SecretKeyActivationWidget::~SecretKeyActivationWidget()
{
    delete ui;
}

void SecretKeyActivationWidget::paintEvent(QPaintEvent *event)
{
    Interface interface;
    interface.setFontSize(ui->label);
}

void SecretKeyActivationWidget::on_returnbtn_clicked()
{
    qDebug()<<"on_returnbtn_clicked";
    ui->activebtn->setEnabled(false);
    emit returnSignal();
}

int SecretKeyActivationWidget::serialNumberCheck(QString key)
{
    // 加密范围字符
    QString base_char = "B2CE3FGHJ4KM6P7QRTV8WX9Y";
    // 校验码的序列字符
    QString index_char = "0123456789abcdef";
    //检验每个字符是否在允许的列表里
    Q_FOREACH(QChar c, key)
    {
        if(!base_char.contains(c))
            return -1;
    }

    if(key.length()!=20)
        return -2;
    //取第一部分数值，即获知服务序列号部分的长度
    int len=base_char.indexOf(key.at(0));
    //从产品密钥第二部分还原服务序列号
    QString str=key.mid(1,len);
    int serial_number=0;
    Q_FOREACH(QChar c, str)
        serial_number=serial_number*24+base_char.indexOf(c);

    qDebug()<<"Key Decode:"<<serial_number;
    QString serial=get_serial_number();
    if((serial.length()==7 && serial.mid(4,2)!=QString::number(serial_number).mid(5,2)) ||
            (serial.length()==8 && serial!=QString::number(serial_number)))
        return -3;

    //校验
    //对前18位组成的字符串取md5，取第一个和第二个校验值
    QString body=key.mid(0,18);
    QString md5;
    QByteArray by=QCryptographicHash::hash(body.toUtf8(),QCryptographicHash::Md5);
    md5.append(by.toHex());
    QChar last_check_num_f = base_char.at(index_char.indexOf(md5.at(0)));
    QChar last_check_num_s = base_char.at(index_char.indexOf(md5.at(1)));
    //第一位校验码参照值
    QChar f_last_check_num = key.at(18);
    //第二位校验码参照值
    QChar s_last_check_num = key.at(19);

    if(last_check_num_f == f_last_check_num && last_check_num_s == s_last_check_num)
        return 0;
    else
        return -4;

    return -5;
}

void SecretKeyActivationWidget::activeSys(QString serial, QString code)
{
    gint activation= 1;
    activation = new_active_code(serial.toLocal8Bit().data(), code.toLatin1().data());
    QString ret = kylin_activation_get_result_message(activation);
    if(ret == "")
        ret = tr("Invalid activation code");
    if (activation == 0)
    {
        emit activationMessageSignal(activation);
        emit activateSucceed();
    }
    else
    {
        QMessageBox::about(this,  NULL, QString(ret+ tr("!(error code#" )+ QString::number(activation).rightJustified(4,'0')  +")"));
    }
}

void SecretKeyActivationWidget::on_activebtn_clicked()
{
    resetControlsState(-1);
    m_timer->start(100);

    errorText.clear();
    QString key=ui->aclineEdit->text();
    int ret = 1;
    if(key.length()==20)
    {
        ret=serialNumberCheck(key);
        qDebug()<<"[Key check:]"<<key.length()<<ret;
        if(0==ret)
        {
            QString url;
            url=QString("https://wx.kylinos.cn/api/cdkey_activation.json?f=%1&k=%2&y=%3")
                    .arg(get_serial_number())
                    .arg(key)
                    .arg(get_encrypted_hardware_info());

            qDebug()<<"HTTP GET:"<<QUrl::toPercentEncoding(url,"/:&%=?"," ");
            QNetworkRequest request;
            QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
            //        request.setUrl(QUrl(QUrl::toPercentEncoding(url,"/:&%=?"," ")));
            request.setUrl(QUrl(url));
            naManager->get(request);
            connect(naManager,&QNetworkAccessManager::finished,this,[=](QNetworkReply* reply){
                QNetworkReply::NetworkError err = reply->error();
                if(err == QNetworkReply::NoError)
                {
                    QJsonParseError error;
                    QJsonDocument readDoc=QJsonDocument::fromJson(reply->readAll(),&error);
                    if(!readDoc.isNull() && error.error==QJsonParseError::NoError)
                    {
                        int errcode=readDoc.object().value("errcode").toInt();
                        switch (errcode) {
                        case 0:
                        {
                            QJsonObject obj=readDoc.object().value("data").toObject();
                            if(!obj.value("SERIAL").toString().isEmpty() && !obj.value("KEY").toString().isEmpty())
                                activeSys(obj.value("SERIAL").toString(),obj.value("KEY").toString().remove("-"));

                        }
                            break;
                        case 400:
                            errorText=tr("The request parameters are incomplete");
                            break;
                        case 401:
                            errorText=tr("The service serial number is wrong");
                            break;
                        case 402:
                            errorText=tr("The product key and system version do not match");
                            break;
                        case 403:
                            errorText=tr("The product key has been used");
                            break;
                        case 404:
                            errorText=tr("Incorrect product key input");
                            break;
                        case 405:
                            errorText=tr("Hardware code parsing failed");
                            break;
                        case 500:
                            errorText=tr("Server error");
                            break;
                        default:
                            break;
                        }
                    }
                }
                else
                    errorText=tr("Unable to connect to the network");

                reply->deleteLater();

                if(!errorText.isEmpty())
                {
                    QMessageBox *box=new QMessageBox(QMessageBox::Warning, NULL, errorText,QMessageBox::NoButton,this);
                    QPushButton *closeButton = box->addButton(tr("Close"), QMessageBox::AcceptRole);
                    box->setDefaultButton(closeButton);
                    box->exec();
                    delete box;
                }
                m_timer->stop();
                resetControlsState(0);
            });
        }
        else
        {
            if(ret<0)
                errorText=tr("Product key is not correct");
        }
    }
    else
    {
        errorText=tr("Please enter 20-digit product key");
    }

    if(!errorText.isEmpty())
    {
        QMessageBox *box=new QMessageBox(QMessageBox::Information, NULL, errorText,QMessageBox::NoButton,this);
        QPushButton *closeButton = box->addButton(tr("Close"), QMessageBox::AcceptRole);
        box->setDefaultButton(closeButton);
        box->exec();
        delete box;
    }
//    ui->activationiconlabel->setVisible(false);
    if(ret != 0)
    {
        m_timer->stop();
        resetControlsState(0);
    }
}

void SecretKeyActivationWidget::clearData()
{
    ui->aclineEdit->clear();
}

void SecretKeyActivationWidget::resetControlsState(int type)
{
    if(type == 0)
    {
        ui->activationiconlabel->setVisible(false);
        ui->activationremindlabel->setVisible(false);
        ui->returnbtn->setEnabled(true);
        ui->activebtn->setEnabled(true);
    }
    else
    {
        ui->activationiconlabel->setVisible(true);
        ui->activationremindlabel->setVisible(true);
        ui->returnbtn->setEnabled(false);
        ui->activebtn->setEnabled(false);
    }
}
